<?php
//FIXME mettre les commentaire et terminer la classe
final class Date extends SerialisableObject
{
        const MYSQL_DATE = "Y/m/d h:m:i";
        
        private $_timestamp;
        
        public function __construct($time = "default_timestamp")
        {
                if( $time != "default_timestamp")
                {
                        $this->_timestamp = strtotime($time);
                }
                else
                {
                        $this->_timestamp = time();
                }
        }
        
        public function __destruct()
        {
                
        }
        
        public function __toString()
        {
                return "Instance of date";
        }
        
        public function getDate( $format )
        {
                switch( $format )
                {
                        case Date::MYSQL_DATE :
                                return date(Date::MYSQL_DATE, $this->_timestamp);
                        break;
                }
        }
        
        protected function _formatToXml()
        {
                
        }
}
  /*
class Date implements Throwaway
{

	private $_timestamp;

	private $_timestamp_null;
	const MYSQL_FORMAT			 = 	0;	//Format mysql
	const FULL_INT_DATE_FORMAT   =  1;  //ex : 13/11/2011 11:11:11
	const YMD_STR_DATE_FORMAT 	 =  2;  //ex : 13 Novembre 2011
	const YMD_INT_DATE_FORMAT 	 =  3;  //ex : 13/11/2011
	const YMD_SHORT_STR_FORMAT 	 =  4;  //ex : 13 nov 2011
	const FULL_STR_DATE_FORMAT 	 =  5;  //ex : 13/11/2011 à 11h11
	const YMD_COLL_STR_FORMAT 	 =  6;  //ex : 20111113
	const TIMESTAMP 			 = 	7;	//ex 1321531770
	const MYSQL_ONLY_DATE_FORMAT =  8;  //Format mysql (uniquement la date, sans l'heure)
	const ONLY_YEAR_FORMAT 		 =  9;  //ex : 2011
	const ONLY_MONTH_FORMAT 	 = 10;  //ex : 11
	const ONLY_DAY_FORMAT 		 = 11;  //ex : 13

	const YMD_COMPARE = "Y/m/d"; //ex : 13/11/2011 != 16/11/2011
	const YM_COMPARE = "Y/m";    // ex : 11/2011 == 11/20011
	const FULL_COMPARE = "full"; //ex : 13/11/2011 11:11:11 != 13/11/2011 11:11:12

	static private $mois_txt = array("", DATE_MOIS_1, DATE_MOIS_2, DATE_MOIS_3, DATE_MOIS_4,
									 DATE_MOIS_5, DATE_MOIS_6, DATE_MOIS_7, DATE_MOIS_8,
									 DATE_MOIS_9, DATE_MOIS_10, DATE_MOIS_11, DATE_MOIS_12);
	static private $mois_short_txt = array("", DATE_MOIS_SHORT_1, DATE_MOIS_SHORT_2, DATE_MOIS_SHORT_3, DATE_MOIS_SHORT_4,
										   DATE_MOIS_SHORT_5, DATE_MOIS_SHORT_6, DATE_MOIS_SHORT_7, DATE_MOIS_SHORT_8,
										   DATE_MOIS_SHORT_9, DATE_MOIS_SHORT_10, DATE_MOIS_SHORT_11, DATE_MOIS_SHORT_12);

	static private $jour_txt = array(DATE_DAYS_7,DATE_DAYS_1,DATE_DAYS_2,DATE_DAYS_3,DATE_DAYS_4,DATE_DAYS_5,DATE_DAYS_6);

	static public function getMoistxt($num)
	{
		if( array_key_exists($num, self::$mois_txt) )
		{
			return self::$mois_txt[$num];
		}
		else if ($num == -1 )
		{
			return self::$mois_txt;
		}
		else
		{
			throw new ExtendedException("Failed to return month name, bad param in ".__METHOD__." : ".$num,"010001");
		}
	}

	static public function getMoisShortTxt($num)
	{
		if( array_key_exists($num, self::$mois_short_txt) )
		{
			return self::$mois_short_txt[$num];
		}
		else
		{
			throw new ExtendedException("Failed to return month name, bad param in ".__METHOD__." : ".$num,"010001");
		}
	}
  
	static public function getJourtxt($num)
	{
		if( array_key_exists($num, self::$jour_txt) )
		{
			return self::$jour_txt[$num];
		}
		else
		{
			throw new ExtendedException("Failed to return day name, bad param in ".__METHOD__." : ".$num,"010001");
		}
	}
  
	public function __construct($time = '|0455w0r0|')
	{
		if( $time != '|0455w0r0|' )
		{
			if( is_int($time) )
			{
				if( $time > 0 )
				{
					$this->_timestamp = $time;
					$this->_timestamp_null = false;
				}
				else
				throw new ExtendedException("Failed to initiaze date, bad param in ".__METHOD__." : ".var_export($time, true),"010001");
			}
			else
			{
				if($time != NULL && $time != "" && $time != "DEFAULT" && $time != " - " && $time != "0000-00-00 00:00:00" && $time != "0000-00-00")
				{
					$time = str_replace ( "/" , "-", $time);
					$tmp_time = strtotime($time);
					if( $tmp_time !== false )
					{
						$this->_timestamp = $tmp_time;
					}
					else
					{
						throw new ExtendedException("Failed to initiaze date, bad param in ".__METHOD__." : ".var_export($time, true),"010001");
					}
					$this->_timestamp_null = false;
				}
				else
				{
					$this->_timestamp_null = true;
				}
			}
		}
		else
		{
			$this->_timestamp = time();
			$this->_timestamp_null = false;
		}
	}
	
	public function __destruct()
	{
		unset($this->_timestamp, $this->_auto_init, $this->_timestamp_null);
	}
	
	public function __toString()
	{
		return $this->formatDate(Date::FULL_INT_DATE_FORMAT);
	}
  
	public function isNull()
	{
		return $this->_timestamp_null;
	}
	
	public function isOuvre($timestamp = NULL)
	{
		if( $timestamp == NULL)
		{
			$timestamp = $this->_timestamp;
		}
		if( $timestamp != 0 )
		{
			$d = new Date($timestamp);
			$param = array( ":date" => $d->formatDate(Date::MYSQL_FORMAT));
			$query = "SELECT date_jour FROM ".DB_CONFIG.".config_jours_off
					  WHERE date_jour = :date";
			$resultSet = new DataBaseStatement($query);
			$resultSet->query($param);
			if( $resultSet->count() == 1 )
			{
				return false;
			}
			else
			{
				return true;
			}
		}
		else
		throw new ExtendedException("Failed to determined opening/closing day, bad param in ".__METHOD__." : ".var_export($timestamp, true),"010001");
	}
 
	public function formatDate($format)
	{
		$fd = new FormatDate();
		if( !$this->isNull() )
		{
			switch($format)
			{
				case self::MYSQL_FORMAT:
					return $fd->format( $this->_timestamp, DATE_MYSQL_FORMAT);
					break;

				case self::FULL_INT_DATE_FORMAT://11/11/2011 11:11:11
					return $fd->format( $this->_timestamp, DATE_EXTEND_FORMAT);
					break;
					
				case self::YMD_STR_DATE_FORMAT://11 Novembre 2011
					$tmp_date = $fd->format($this->_timestamp, ":Y: |m| (d)");
					$year = substr($tmp_date, strpos($tmp_date,":")+1, 4);
					$month = self::getMoistxt(intval(substr($tmp_date, strpos($tmp_date,"|")+1, 2)));
					$day = substr($tmp_date, strpos($tmp_date,"(")+1, 2);
					return sprintf(DATE_YMD_STR_FORMAT, $year, $month, $day);
					break;
					
				case self::YMD_INT_DATE_FORMAT://11/11/2011
					return $fd->format( $this->_timestamp, DATE_YMD_FORMAT);
					break;
					
				case self::YMD_SHORT_STR_FORMAT://11 nov 2011
					$tmp_date = $fd->format($this->_timestamp, ":Y: |m| (d)");
					$year = substr($tmp_date, strpos($tmp_date,":")+1, 4);
					$month = self::getMoisShortTxt(intval(substr($tmp_date, strpos($tmp_date,"|")+1, 2)));
					$day = substr($tmp_date, strpos($tmp_date,"(")+1, 2);
					return sprintf(DATE_YMD_STR_FORMAT, $year, $month, $day);
					break;
					
				case self::FULL_STR_DATE_FORMAT://11/11/2011 à 11h11
					$content = $fd->format($this->_timestamp, DATE_YMDHI_STR_FORMAT);
					$content = str_replace(":" , DATE_SEPA_YMD_TO_HIS, $content);
					$content = str_replace("|" , DATE_SEPA_HIS_STR, $content);
					return $content;
					break;
					
				case self::YMD_COLL_STR_FORMAT: //20111111
					return $fd->format( $this->_timestamp, "Ymd");
					break;
					
				case self::TIMESTAMP://1321531770
					return $this->_timestamp;
					break;
					
				case self::MYSQL_ONLY_DATE_FORMAT:
					return date("Y-m-d", $this->_timestamp);
					break;

				case self::ONLY_YEAR_FORMAT:
					return date("Y", $this->_timestamp);
					break;
					
				case self::ONLY_MONTH_FORMAT:
					return date("m", $this->_timestamp);
					break;
					
				case self::ONLY_DAY_FORMAT:
					return date("d", $this->_timestamp);
					break;
					
				default:
					throw new ExtendedException("Failed to format Date, bad param in ".__METHOD__." : ".var_export($format, true), "100001","010001");
			}
		}
		else if($this->isNull() && $format == self::MYSQL_FORMAT)
		{
			// On suppose que toutes les dates ont une valeur par défaut, dont NULL si NULL allowed
			return "0000-00-00 00:00:00"; 
		}
		else
		{
			return "";
		}
	}
  
	public function addDay($nbs = 1)
	{
		$this->modDate($nbs, "+|day");
		return $this;
	}
	
	public function subDay($nbs = 1)
	{
		$this->modDate($nbs, "-|day");
		return $this;
	}
	
	public function addMonth($nbs = 1)
	{
		$this->modDate($nbs, "+|month");
		return $this;
	}
	
	public function subMonth($nbs =1)
	{
		$this->modDate($nbs, "-|month");
		return $this;
	}
	
	public function addYear($nbs =1)
	{
		$this->modDate($nbs, "+|year");
		return $this;
	}
	
	public function subYear($nbs =1)
	{
		$this->modDate($nbs, "-|year");
		return $this;
	}
	
	private function modDate($nbs, $scale)
	{
		if( is_numeric($nbs) && intval($nbs) > 0 )
		{
			$option = explode("|", $scale);
			if( $option[0] == "-" || $option[0] == "+" )
			{
				if($option[1] == "day" || $option[1] == "month" || $option[1] == "year")
				{
					$this->_timestamp = strtotime($option[0].$nbs." ".$option[1],$this->_timestamp);
					return true;
				}
				else
				{
					throw new ExtendedException("Failed to modify Date, bad type of modification param in ".__METHOD__." : ".var_export($scale, true), "100001","010001");
				}
			}
			else
			{
				throw new ExtendedException("Failed modify Date, bad type of modification param in ".__METHOD__." : ".var_export($scale, true), "100001","010001");
			}
		}
		else
		{
			throw new ExtendedException("Failed modify Date, bad number param in ".__METHOD__." : ".var_export($nbs, true),"010001");
		}
			return false;
	}
	
	public function setTime($time)
	{
		try
		{
			$tmp = new Date($time);
			$this->_timestamp = $tmp->formatDate(Date::TIMESTAMP);
			$this->_timestamp_null = $tmp->isNull();
			unset($tmp);
		}
		catch(ExtendedException $ee)
		{
			throw new ExtendedException($ee->getMessage(), $ee->getCode(), $this);
		}
		return $this;
	}
	
	public function getInterval(Date $mate, $stringMode = true)
	{
		$content = "";
		$duree = $this->_timestamp - $mate->_timestamp;
		if( $duree < 0 )
		{
			$duree *= -1;
		}	
		if( !$stringMode )
		{
			return $duree;
		}
		else
		{
			return Date::getDureeToString($duree);
		}
	}
	
	public static function getDureeToString($duree)
	{
		if( $duree < 0 )
			$durre *= -1;
		
		if( $duree > 60 )
		{
			$sec = $duree%60;
			$min = intval($duree/60);
			if( $min > 60 )
			{
				$heure = intval($min/60);
				$min = $min%60;
				if( $heure > 24 )
				{
					$jour = intval($heure/24);
					$heure = $heure%24;
					if( $jour > 365 )
					{
						$an = intval($jour/365);
						$jour = $jour%365;
						$content = $an.DATE_INIT_ANNEE." ".$jour.DATE_INIT_JOUR." ".$heure.DATE_INIT_HEURE." ".$min.DATE_INIT_MIN." ".$sec.DATE_INIT_SECONDE;
					}
					else
					$content = $jour.DATE_INIT_JOUR." ".$heure.DATE_INIT_HEURE." ".$min.DATE_INIT_MIN." ".$sec.DATE_INIT_SECONDE;
				}
				else
				$content = $heure.DATE_INIT_HEURE." ".$min.DATE_INIT_MIN." ".$sec.DATE_INIT_SECONDE;
			}
			else
			$content = $min.DATE_INIT_MIN." ".$sec.DATE_INIT_SECONDE;
		}
		else
		{
			$content = intval($duree)." ".DATE_SECONDE;
		}
		return $content;
	}
	
	public function compare(Date $mate, $scale = Date::YMD_COMPARE)
	{
		if( !$this->isNull() )
		{ 
			switch( $scale )
			{
				case Date::FULL_COMPARE:
					if( $this->_timestamp == $mate->_timestamp )
					return true;
					else
					return false;
					break;
						
				case Date::YM_COMPARE:
					if( date(Date::YM_COMPARE,$this->_timestamp) == date(Date::YM_COMPARE, $mate->_timestamp) )
					return true;
					else
					return false;
					break;
						
				case Date::YMD_COMPARE:
					if( date(Date::YMD_COMPARE,$this->_timestamp) == date(Date::YMD_COMPARE, $mate->_timestamp) )
					return true;
					else
					return false;
					break;
						
				default:
					throw new ExtendedException("Bad type of equality in ".__METHOD__." : ".var_export($scale,true),"010001");
			}
		}
		else
		{
			throw new ExtendedException("Try to compare a date with a not initialized Date.", "200002","010001");
		}
	}
	
	public function goToEndOfDay()
	{
		if( !$this->isNull() )
		{
			//On va a minuit du jour d'aprés et on enlève une seconde
			$this->_timestamp = strtotime("+1 day midnight", $this->_timestamp)-1;
			return $this;
		}
		else
		{
			throw new ExtendedException("Try to go to end of day of a not initialized Date.", "200001","010001");
		}
	}
}*/

?>